#include <stdio.h>
#define DEBUG_PRINT
#include "KuniMLPTrainer.h"
#include <memory>
double x[10000][16];
int t[10000][26];
double test_x[10000][16];
int test_t[10000][26];

void read_data()
{
	FILE *fp=fopen("data.txt","r");
	char c;
	int vec[16];
	for(int i=0;i<10000;i++)
	{
		fscanf(fp,"%c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",&c,vec,vec+1,vec+2,vec+3,vec+4,vec+5,vec+6,vec+7,vec+8,vec+9,vec+10,vec+11,vec+12,vec+13,vec+14,vec+15);
		c-='A';
		for(int j=0;j<26;j++)
		{
			if(j==c)
				t[i][j]=1;
			else
				t[i][j]=0;
		}
		for(int j=0;j<16;j++)
		{
			x[i][j]=vec[j]/15.0;
		}
	}

	for(int i=0;i<10000;i++)
	{
		fscanf(fp,"%c %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",&c,vec,vec+1,vec+2,vec+3,vec+4,vec+5,vec+6,vec+7,vec+8,vec+9,vec+10,vec+11,vec+12,vec+13,vec+14,vec+15);
		c-='A';
		for(int j=0;j<26;j++)
		{
			if(j==c)
				test_t[i][j]=1;
			else
				test_t[i][j]=0;
		}
		for(int j=0;j<16;j++)
		{
			test_x[i][j]=vec[j]/15;
		}
	}
	fclose(fp);
}
#include <Windows.h>
int main()
{
//	/*int pctr_counts0[]={10,10,10,10,1};
//	int pctr_counts1[]={100,100,100,100,1};
//	int pctr_counts2[]={30,30,30,30,1};
//	int pctr_counts3[]={30,30,30,30,1};
//
//	KuniMLP* mlps=new KuniMLP[4];
//	new (mlps)KuniMLP(1.0,0,2,1,5,pctr_counts0);
//	new (mlps+1)KuniMLP(1.0,0,2,1,5,pctr_counts1);
//	new (mlps+2)KuniMLP(1.0,0,2,1,5,pctr_counts2);
//	new (mlps+3)KuniMLP(2,0,2,1,5,pctr_counts3);
//
//	double x[10][2]={0,0, 1,0, 0,1, 1,1, 0.1,0.1, 0.9,0.1, 0.1,0.9, 0.9,0.9, 0.2,0.8, 0.8,0.2};
//	int t[10][1]={0, 1, 1, 0, 0, 1, 1, 0, 1, 1};
//	double rates[4]={0.01,0.05,0.01,0.05};
//	KuniMLPTrainer trainer(mlps,4,10,(double*)(x),(int*)(t),2,1,rates,0.0001,300000);
//	trainer.Train();
//	printf("%lf %lf %lf %lf\n",trainer.m_pBestErrors[0],trainer.m_pBestErrors[1],trainer.m_pBestErrors[2],trainer.m_pBestErrors[3]);
//	double x_[2]={0.6,0.4};
//	for(int i=0;i<4;i++)
//	{
//		mlps[i].Stimulate(x_);
//		printf("%lf ",mlps[i].m_pO[0]);
//	}*/
////	double   x[20][30] = { //0 1 2 3 4 5 6 7 8 9 4 5 7 3 2 4 0 9
////				{ 0,1,1,1,0,
////				  1,0,0,0,1,
////				  1,0,0,0,1,
////				  1,0,0,0,1,
////				  1,0,0,0,1,
////				  0,1,1,1,0,},
////
////				{ 0,1,1,1,0,
////				  1,0,0,0,1,
////				  1,0,1,1,1,
////				  1,1,1,0,1,
////				  1,0,0,0,1,
////				  0,1,1,1,0,},
////
////				{ 0,0,1,0,0,
////				  0,0,1,0,0,
////				  0,0,1,0,0,
////				  0,0,1,0,0,
////				  0,0,1,0,0,
////				  0,0,1,0,0,},
////
////				{ 0,0,1,0,0,
////				  0,1,1,0,0,
////				  0,0,1,0,0,
////				  0,0,1,0,0,
////				  0,0,1,0,0,
////				  0,1,1,1,0,},
////
////				{ 0,1,1,1,0,
////				  1,0,0,0,1,
////				  0,0,0,0,1,
////				  0,0,1,1,0,
////				  0,1,0,0,0,
////				  1,1,1,1,1,},
////
////				{ 1,1,1,1,1,
////				  0,0,0,0,1,
////				  0,0,0,0,1,
////				  0,1,1,1,1,
////				  1,0,0,0,0,
////				  1,1,1,1,1,},
////				       
////				{ 0,1,1,1,0,
////				  1,0,0,0,1,
////				  0,0,1,1,0,
////				  0,0,0,1,0,
////				  1,0,0,0,1,
////				  0,1,1,1,0,},
////
////				{ 1,1,1,1,1,
////				  0,0,0,0,1,
////				  0,1,1,1,1,
////				  0,0,0,0,1,
////				  0,0,0,0,1,
////				  1,1,1,1,1,},
////
////				{ 0,0,0,1,0,
////				  0,0,1,1,0,
////				  0,1,0,1,0,
////				  1,1,1,1,1,
////				  0,0,0,1,0,
////				  0,0,0,1,0,},
////
////				{ 0,0,0,1,0,
////				  1,0,0,1,0,
////				  1,0,0,1,0,
////				  1,1,1,1,1,
////				  0,0,0,1,0,
////				  0,0,0,1,0,},
////
////				{ 1,1,1,1,1,
////				  1,0,0,0,0,
////				  1,1,1,1,0,
////				  0,0,0,0,1,
////				  1,0,0,0,1,
////				  0,1,1,1,0,}, 
////
////				{ 1,1,1,1,1,
////				  1,0,0,0,0,
////				  1,1,1,1,1,
////				  0,0,0,0,1,
////				  0,0,0,0,1,
////				  1,1,1,1,1,},
////
////				{ 0,1,1,1,0,
////				  1,0,0,0,0,
////				  1,1,1,1,0,
////				  1,0,0,0,1,
////				  1,0,0,0,1,
////				  0,1,1,1,0,},
////
////				{ 1,1,1,1,1,
////				  1,0,0,0,0,
////				  1,1,1,1,1,
////				  1,0,0,0,1,
////				  1,0,0,0,1,
////				  1,1,1,1,1,},
////
////				{ 1,1,1,1,1,
////				  0,0,0,0,1,
////				  0,0,0,1,0,
////				  0,0,1,0,0,
////				  0,0,1,0,0,
////				  0,0,1,0,0,},
////
////				{ 1,1,1,1,1,
////				  1,0,0,0,1,
////				  0,0,0,0,1,
////				  0,0,0,1,0,
////				  0,0,0,1,0,
////				  0,0,0,1,0,}, 
////
////				{ 0,1,1,1,0,
////				  1,0,0,0,1,
////				  0,1,1,1,0,
////				  1,0,0,0,1,
////				  1,0,0,0,1,
////				  0,1,1,1,0,},
////
////				{ 1,1,1,1,1,
////				  1,0,0,0,1,
////				  1,1,1,1,1,
////				  1,0,0,0,1,
////				  1,0,0,0,1,
////				  1,1,1,1,1,},
////
////				{ 1,1,1,1,1,
////				  1,0,0,0,1,
////				  1,1,1,1,1,
////				  0,0,0,0,1,
////				  0,0,0,0,1,
////				  1,1,1,1,1,},
////
////				{ 0,1,1,1,0,
////				  1,0,0,0,1,
////				  1,0,0,0,1,
////				  0,1,1,1,1,
////				  0,0,0,0,1,
////				  0,1,1,1,0,}
////};
////
////
/////* desired outputs */
////int   t[20][10] = { 
////				{ 1,0,0,0,0,0,0,0,0,0 },
////				{ 1,0,0,0,0,0,0,0,0,0 },
////				{ 0,1,0,0,0,0,0,0,0,0 },
////				{ 0,1,0,0,0,0,0,0,0,0 },
////				{ 0,0,1,0,0,0,0,0,0,0 },
////				{ 0,0,1,0,0,0,0,0,0,0 },
////				{ 0,0,0,1,0,0,0,0,0,0 },
////				{ 0,0,0,1,0,0,0,0,0,0 },
////				{ 0,0,0,0,1,0,0,0,0,0 },
////				{ 0,0,0,0,1,0,0,0,0,0 },
////				{ 0,0,0,0,0,1,0,0,0,0 },
////				{ 0,0,0,0,0,1,0,0,0,0 },
////				{ 0,0,0,0,0,0,1,0,0,0 },
////				{ 0,0,0,0,0,0,1,0,0,0 },
////				{ 0,0,0,0,0,0,0,1,0,0 },
////				{ 0,0,0,0,0,0,0,1,0,0 },
////				{ 0,0,0,0,0,0,0,0,1,0 },
////				{ 0,0,0,0,0,0,0,0,1,0 },
////				{ 0,0,0,0,0,0,0,0,0,1 },
////				{ 0,0,0,0,0,0,0,0,0,1 } };
//	double x[10][2]={0,0, 1,0, 0,1, 1,1, 0.1,0.1, 0.9,0.1, 0.1,0.9, 0.9,0.9, 0.2,0.8, 0.8,0.2};
//	int t[10][1]={0, 1, 1, 0, 0, 1, 1, 0, 1, 1};
//	//KuniMLPTrainer trainer(20,0,3,50,100,20,(double*)(x),(int*)(t),30,10,0.01,100000);
//	KuniMLPTrainer trainer(20,0,3,50,100,10,(double*)(x),(int*)(t),2,1,0.01,100000);
//	trainer.Train();
//	/*double x_[30]=
//				{ 0,0,1,0,0,
//				  0,1,1,0,0,
//				  0,0,1,0,0,
//				  0,0,1,0,0,
//				  0,0,1,0,0,
//				  0,0,1,0,0,};*/
//	double x_[2]={0.1,0.7};
//	trainer.m_pMLPs[trainer.m_nBestMLPIndex].Stimulate(x_);
//	for(int i=0;i<10;i++)
//		printf("%lf ",trainer.m_pMLPs[trainer.m_nBestMLPIndex].m_pO[i]);
	

	omp_set_num_threads(20);
	read_data();
	KuniMLPTrainer trainer(1,0,3,40,50,500,(double*)x,(int*)t,16,26,0.1,100*30000,0.9,100*30000);
	trainer.Train();
	
	return 0;
}